看雪2018峰会回顾 | 从WPA2四次握手看KRACK密钥重装攻击
石冰
CISP-PTE注册渗透测试工程师,OWASP中国分会项目研究小组研究员,i春秋平台安全讲师,数学与信息安全爱好者,CTF竞赛爱好者。本科信息安全专业大三在读,擅长软件逆向,目前主攻密码学。平时喜爱研究渗透、逆向、取证等各类安全技术。
以下内容为石冰在看雪2018安全开发者峰会上的演讲实录:
我的议题是“从WPA2四次握手看KRACK密钥重装攻击”,这次的漏洞或者这次攻击方式是处于协议层面爆发出来的问题,这和前面提到的TCP侧信道的攻击一样,属于协议层面的漏洞。这次分享没有办法很短时间内把这个问题分析透彻,但我接下来尽可能用通俗的语言把这个问题解释清楚,看一下去年年底的这次影响很大的事件到底说了什么东西。
自我介绍
我自己是一名学生,在读大三。安全这个领域是我自己从小到大非常感兴趣的一个领域,而且平时也很喜欢花时间研究各种各样的安全技术。安全对企业是个严肃的话题,但对于我来讲,我从小是一直把这个东西当作玩的事情去做,我为什么会去研究?因为很大程度觉得这个东西很好玩,其他东西都是基于在这个兴趣之上的。包括是CTF,还是平时发现漏洞也好,如果对这个东西有兴趣就很容易投入进去。如果对这个议题感兴趣,也可以在会议之后和我继续交流。
KRACK是什么?
关于WPA2漏洞,大家在去年年底或多或少都有了解,去年年底公开这个细节之后,媒体和新闻采用很大的篇幅去报道这个漏洞。这个消息刚一放出来时,我只是简单的看了一下,因为我印象里WPA2协议被证明过是一个安全的协议,而且它复议很长一段时间,一直没有出现很重大的问题,这次直接爆出属于协议层面的问题,应该属于严重的漏洞范围。但最开始只是简单的看了一下,并没有深入的了解。
我对它真正感兴趣是在细节公开的几个月之后,我突然想起来这个事件这么严重,怎么没过多长时间就已经没动静了。我回过头来找新闻报道去看,发现很多新闻报道不仅对漏洞原理没有解释清楚,连攻击能干什么也没有说清楚,就一直反复强调“这个问题很严重”,这让我当时想进一步了解一下这次事件到底说了什么问题,于是有了后续的研究。
KRACK攻击是什么?KRACK是我们说的密钥重装攻击,它属于重放攻击,这个攻击的范围很有限,因为它需要搞中间人攻击。主要是利用了WPA和WPA2协议的漏洞,当客户端连接一个WiFi时,四次握手过程被触发,这个过程中有一个ap向客户端传送msg3的过程,攻击者控制这个过程反复传msg3,导致客户端Nonce被重置,进而导致后面传输的数据可以被攻击和解密,这是KRACK攻击的大致流程。
至于攻击是如何实现的,需要我们对漏洞的原理有一个大致的了解,因为这个问题出现在四次握手过程中,我们先回到四次握手本身来看一下这个问题到底出在了什么地方。
四次握手分析
先明确几个概念,四次握手过程会通过四次握手来产生PTK的后话密钥。PTK的生成一般包含5个部分,前2个分别是aNonce和sNonce,这个Nonce就是密钥学随机数的概念,我们在客户端ap通信的过程当中,把ap叫“authenticator”,表示认证方;在客户端叫“supplicant”,表示请求方。aNonce和sNonce是表示客户端ap那端产生的两个随机数,在这区分了一下。下面的两个也是一样的,a和s分别表示两端的地址。Pmk是主密钥,它既可以看作是由另外一个用户响应密钥来生成的,但它又不是由单独的psk来生成,它还包括其他的参数,共同组成了pmk。这个pmk不是用来加密数据的,它和我们前面提到的另外4个部分共同组合成了PTK,这个PTK是后面真正用来加密传输数据的钥匙,这个是我们首先需要明确的。
我们看一下四次握手的过程,第一个是传送给客户端的msg1,这个msg1主要包含两个东西,一个是ap这边传的随机数,还有一个是r,r在这表示一个计数器的意思,它会随着每发送一个报文自动加1,对于同一次传送的回应过程中使用的是同一个r,也就是说可以看到它这个载体下回映的报文当中使用函数。在客户端ap进行四次握手之前,它们会预先进行认证和关联的过程,在这个过程当中PTK需要5个部分,其中有4个部分在前面已经准备好了,也就是说对于客户端来讲,现在如果它想生成一个PTK的话就缺一个aNonce,也就是说它就等于aNonce。
现在通过四次握手的第一个阶段,msg1把这个aNonce传过去了,比如客户端在这边,它的5样东西都已经集齐了,它现在可以生成一个PTK。但是客户端这边生成之后,ap这边还没有,所以这边握手一个msg2过去。
这个msg2也包含两个东西,一个是sNonce,表示客户端产生的随机数,还有一个是这个r,和前面的那个authenticator保持一致。Ap这边也就等sNonce过来了,它现在有了这个sNonce也是5样东西都集齐了,所以它这边也可以生成一个PTK。这样通信两端进行秘密通信,它的密钥都已经完毕了。也就是说四次握手的前两次握手过程解决了PTK密钥生成的问题。
我们看一下第三次握手,ap生成PTK之后还会进行一个验证,如果这边都没有什么问题了,这里又回一个msg3过去。这个msg3也主要包含两个部分,一个是主密钥防阻隔时用的,还有一个是authenticator+1,因为是我们这个ap这边相当于第二次给客户端发报文了,所以这里的值自动加1。客户端收到msg3的时候回一个msg4过来,这个msg4在这相当于msg3的ACK,起到一个确认的作用。它既然是一个ACK的话,可以想象到ap这边如果没有收到msg4的话会怎样,如它没有收到msg4就肯定认为msg3是丢了,因为我发一个东西过去,那边没有人理我,也没有人回应,那肯定它会重发一个东西过去,所以ap这边只要没有收到msg4就会回应一个msg3过去。但是客户端不会这么想,它才不会管ap有没有收到这个msg4,只要我把msg4和ACK传出去了,我这边的任务就完成了,四次握手就结束了,接下来就是通过PTK来加密数据了,所有通过我客户端发出来的东西都会经过PTK加密。但是ap那边不行,它那边只有收到msg4之后才会安装PTK,否则就会重传msg3,直到它成功的收到了msg4之后认为工作完成了,可以安装一个PTK了。这是四次握手大致的过程。
我们接下来说说客户端这边,它要通过安装的PTK来加密数据了。我们一直在说这个加密,那么它到底是怎么加密的?我们详细来看一下这个过程。这是我们加密的流程,可以看一下上面的明文数据,客户端假如要发送明文数据,它会利用我们的PTK和另一个东西组合成密钥,那个东西就是这个Nonce。前面说到KRACK攻击的原理时,说由于KRACK攻击导致密钥、Noucce被重置,被重置的就是这里的Nonce被重置了,而不是前面四次握手中提到的aNonce或者sNonce,不是那里的那个,很多人都当成了前面那个Nonce,不是前面那个被重置了,只是加密的这个Nonce被重置了。
这个Nonce叫pACKetNumber,它会随着客户端每发送一个报文,这个Nonce会自动加1。我们把这个地方虽然把它叫Nonce,但它一点也不随机,因为它有自己的增长规律。我们在这个地方把PTK和这个Nonce做一个混合,混合成了这个密钥流,每过来一个明文数据,我们就用这个密钥流给它做一个异或运算,这里生成密文数据。
我们看一下这个Nonce,每一个明文数据过来,它的Nonce都一直变化,下一个过来的时候,由于Nonce+1,它的值就变化了。这么做有什么好处?如果我们对密码学有了解的话,就知道加密的人很怕数学统计,如果我们用同一把钥匙加密很多不同的数据,就存在通过数学分析找出它其中规律,进而解密数据的概率。我们现在每个明文数据都使用了一个不同的密钥流,就会在一定程度上相当于降低了这种问题,出现了风险。现在把PTK和Nonce混合成一个密钥流之后,过来一个明文数据,这么混合一下,然后生成一个密钥流,做一个异或运算,得到一个密文数据。
这个时候我们就会发现,因为我们的Nonce在不断变化,导致密钥流也一直在变。如果Nonce被重置了,因为我们的PTK是不变的,所以这个地方Nonce重置等于我们这个密钥流也被重用了。因为四次握手的过程是在WPA2里主要负责协商密钥或者身份认证,真正加密是底下这些东西起到加密作用,这几种加密的方式或者在WPA2协议的加密里面,这个Nonce重用就等于密钥流重用了,这是我们首先需要明确的。
这是四次握手当中加密的流程,看了这个流程之后就,接下来看看攻击环节。
如何攻击msg3传输?
KRACK攻击到底如何进行的?可以分成几步来看:
第一步,客户端如果想试图连接一个WiFi的话,比如这边连信道6,这个过程中正常的、没有问题。攻击者这边做的第一步是通过无线洪水攻击断开客户端和APP之间的连接,它强迫客户端下线。
这种东西怎么去防御?没有太好的办法去防御,因为这种东西不认证也不加密,它不是一个特别讲道理的东西,它让你掉线可能就掉线了,这是一个防不胜防的东西。但是客户端掉线之后,它会试图重新连接APP,这时攻击者可以采用攻击方式,强迫把我们的客户端连到另一个信道。攻击者可以有两块网卡,这边用mitm地址很容易伪造,攻击者把它试图模拟成一个ap,把信道6的东西克隆,通过攻击强迫客户端连接到信道1上,这时攻击者就卡在了两个信道中间,扮演了中间人的角色。
这就是我们的攻击第一步,攻击者首先要想办法卡上中间人的位置,但这时他还不进行任何篡改,客户端和APP之间的流量会经过中间人的传输,但是他不进行任何操作。
第二步,客户端和APP之间进行四次握手过程,前三次握手过程攻击者左手拿到数据之后右手递到另一边,保证数据是正常传递的,在最后一次msg4传输的时候攻击者开始搞事情了,他拿到msg4之后不再递到另一方了,相当于阻断了msg4的传输,截断了这个报文的操作。APP只要没有收到msg4,它就会重新传一个msg3过去,但客户端已经把msg4发过去了,它那边已经认为自己的工作完成了。没有一种机制是ap再回一个ACK过去,那就没完没了了,总得有一个停的时候。所以客户端的msg4只要发过来,它就认为它这边的工作完成了。
四次握手结束了,接下来就用PTK加密数据了,接下来就这个来用加密通讯的数据了。但攻击者在这时阻断了msg4传输,所以这时APP会回传一个msg3过去。这时客户端如果收到重传的msg3会出现什么情况?
第三步,APP传msg3过去,authenticator变成了+2了,表示重传的msg3,攻击者把msg3放回去,让它正常传输到客户端那边,因为它之前传过一次msg4了,这时又收到msg3,它就会想:我之前收到了msg3,现在四次握手都结束了,怎么又收到了msg3?这时客户端做出来的反应动作就是这次密钥重装攻击漏洞爆发的关键。
我们来看看它做出了什么反应,这个地方规定只要客户端收到一个msg3,它就要给出一个msg4做出回应,但是这个地方前面第一次msg4过去之后已经安装PTK了,所以这时它回复的不再是是一个简单的msg4过来,而是一个经过加密之后的msg4。我们看看的加密的符号,上面的1表示使用的Nonce,下面的PTK表示使用的PTK加密。它里面的authenticator+2跟上面有一定连续性,是紧跟上面发了一个包,只不过这里的msg4变成加密了。
我们看一下这个攻击,这里发过来一个加密之后的msg4,到这里就结束了吗?还没有。同时规定回来一个msg4之后,还要重新安装你的PTK,并且将你Nonce重置。这就是比如我们传msg4时给它加密Nonce使用了一个1,下一次发的时候本来这个应该更新的Nonce在这里又回到1了,也就是说我们的Nonce由于msg3重传,它在这里被重置了。接下来我们发完msg4之后,客户端就会重新安装PTK,这个实际上就是我们重传msg3带来的后果。接着看一下密钥重装Nonce在这个地方就已经被重置了。
第四步,这个地方客户端会想:我这边已经收到一个重传的msg3之后,msg4我已经回复过去了,密钥我已经重装了,现在总应该没有其他事情了吧?这时又回到正常的通信过程,客户端开始往APP传输数据。这时因为它之前已经安装过一次PTK,这时肯定传送的是一个加密数据,但由于前面msg3的重传,导致Nonce在这里被重用了,所以这个地方本来是应该更新的一个Nonce,在这里它又回到1了,我们加密数据在这里采用的还是1的Nonce。这里我们可以看到客户端那边传输了两次东西,但是使用的是同一个Nonce,这样一来就会出现问题。
第五步,现在看一下最底下被加密的数据,比如现在攻击者如果想解密这个数据,他需要什么东西?需要我们的密钥流。这个密钥流可以得到吗?可以的。我们先看攻击者手里有哪些东西,由于之前的msg3重转导致msg4回过来一个加密之后的msg4,在之前四次握手过程中客户端还发过来一个明文的msg4,对比这两个msg4可以发现,这两个东西除了authenticator之外是没有什么不同的,authenticator对于msg4本身是没有影响的。现在等于是攻击者有了明文的msg4,以及这个msg4对应的密文,有了这个名文和密文的对应关系之后,在加密的时候采用的密钥流是基于异或的,名文数据通过异或得到了密文数据。
现在攻击者手里有了名文数据和对应的密文数据,现在只要返回来算一下,让名文数据异或密文数据,就就可以倒推出来密钥流。有了这个密钥流之后,我们最担心的问题还是发生了,因为前面本来传输数据时更换了这个密钥,由于Nonce重置导致我们这里加密数据时使用的密钥和前面推导出来的密钥流使用的是同一把密钥,我们就可以使用前面推导出来的密钥流,去解密后面传送的数据,最终实现数据的解密。
这就是KRACK攻击流程中的核心思路,攻击者首先卡上一个中间人的位置,然后去放任四次握手的前三次握手,在最后一次握手过程中阻断msg4传输,导致我们重传msg3、密钥重装,导致Nonce被重置,再通过前面明文和密文的对应关系推导出密钥流,通过密钥流解密被重装之后加密的数据,最终实现数据的解密。
我们知道它的攻击过程之后,可以看看KRACK攻击到底能够实现什么功能,首先,我们知道肯定可以完成重放和解密两个功能。这里根据我们的加密采用的方式不一样,这个KRACK还可以更进一步,如果采用ASE-CCMP的方法顶多完成重放和解密动作,如果采用了wpa-tkip或者后来出的gcmp的方式,攻击者除了重放和解密之外,他还可以完成伪造的步骤。在前面的KRACK没有提到伪造的部分,因为时间有限,如果有兴趣的话,可以会议之后继续交流这部分内容。对于KRACK攻击,不改密码没有事,改了也没有用,因为它根本跟这个东西没有关系。这是KRACK攻击大致能够实现的攻击效果。
我们看一下它的作用范围,前面说到KRACK攻击对我们的系统产生了严重的影响,这里有两类系统产生的影响更一直,就是Linux和安卓系统,为什么是这样?主要原因是出现在WPA上,只有东西它本来是客户端一个加密任务工具,谷歌把它修改后之后加入了安卓平台,所以两边都出事了。为什么说这个东西严重?因为它不仅清除了我们已经安装的密钥,而且它直接用了一个全0密钥代替重装密钥,导致加密过程形同虚设,这时一点安全性都谈不上了。
微软在这个地方受到的影响非常小,从这个表可以发现Windows操作系统直接拒绝了msg3的重传,Windows是挺有意思的一个操作系统,KRACK攻击的核心物种在于客户端劫持msg3的重装。现在微软这里等于是你要重传msg3,但我这边不接受,等于最开始就把KRACK攻击给阻断了。
关于KRACK攻击的作用范围,后面是关于如何对抗KRACK提供一个思路,除此之外,对于个人用户针对KRACK攻击最方便的方法是及时更新或者安装对应补丁。对于企业用户,可以考虑采用WIPS的防御系统,它采用的是和攻击者类似的思路,也是采用链路攻击的方式打掉攻击者的设备而实现保护。
最后是关于这次问题的反思和总结,我们之前说过WPA2协议被证明是安全的,但通过这次爆出来的问题并不冲突,如果我们看一下证明过程就会发现,证明过程就被建立在密钥仅仅被安装一次的前提之上。可以看下这两张图,部分安全并不能代表整体安全,单看每个部分都没有问题,但把它组合在一起就会出现问题。这也为安全领域的证明提出了更高更严谨的要求。
因为咱们今天下午的议题排得比较满,内容有限,如果对这部分内容感兴趣可以在会议之之后联系我。谢谢大家!
*转载请注明来自看雪社区